"""
Provides facilities for managing and rendering fonts.
"""
import threading

import pygame

_DEFAULT_FONT_HEIGHT = 30
_FONT_CACHE = {}
_FONT_LOCK = threading.Lock() #A lock to prevent race conditions on the font-rendering system

def _get_font(name, size):
    #Ensure that the size is valid
    size = size or _DEFAULT_FONT_HEIGHT
    if size < 0:
        size = _DEFAULT_FONT_HEIGHT
        
    #If the font's been registered before, supply the old instance
    existing_font = _FONT_CACHE.get((name, size))
    if existing_font:
        return existing_font
        
    #Set up a new font and cache it
    if name and name.startswith('sys:'): #It's a system-local font
        tokens = name.split(':')[1:]
        if 'i' in tokens:
            tokens.remove('i')
            italic = True
        if 'b' in tokens:
            tokens.remove('b')
            bold = True
        _FONT_CACHE[(name, size)] = font = pygame.font.SysFont(tokens[0], size, italic=italic, bold=bold)
    else: #It's a bundled font, which is the common case
        _FONT_CACHE[(name, size)] = font = pygame.font.Font(name, size)
    return font
    
def render(font, text, antialias=True, colour=(255, 255, 255), background_colour=None, underline=False):
    with _FONT_LOCK:
        font = _get_font(*font)
        if underline:
            font.set_underline(True)
            
        output = None
        if background_colour:
            output = font.render(text, antialias, colour, background_colour)
        else:
            output = font.render(text, antialias, colour)
            
        if underline:
            font.set_underline(False)
            
        return output
        
def get_height(font):
    with _FONT_LOCK:
        return _get_font(*font).get_linesize()
        
def get_width(font, sample):
    with _FONT_LOCK:
        return _get_font(*font).size(sample)[0]
        